package com.webonn.frame.util;

import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Peng on 2017/1/11.
 */
public class ListToTreeUtils {

    private static String CODE = "code";
    private static String PCODE = "pcode";
    private static String NODE = "nodes";
    private static ListToTreeUtils instance;

    /**
     * 将List重组为数
     * 预定：父节点字段名称为 pcode ，主键字段名称为code
     * @param dtoList DTO集合
     * @param rootName 根节点名称  如skr
     * @return List<Map<String, Object>>
     */
    public List<Map<String, Object>> constructDTOToTree(List<Map<String, Object>> dtoList,String rootName){

        //key:父节点ID value:子节点集合 树集合
        Map<Object,List<Map<String, Object>>> dtoMap = new HashMap<>();

        //将List重组到Map中
        dtoList.forEach(dto -> {
            //已经存在的树集合中pid是 dto的pid的list
            List<Map<String, Object>> tempDtoList = dtoMap.get(dto.get(ListToTreeUtils.PCODE));

            //如果是空就加进去
            if (tempDtoList == null){

                tempDtoList = new ArrayList<Map<String, Object>>();

                dtoMap.put(dto.get(ListToTreeUtils.PCODE),tempDtoList);

            }
            //添加项
            tempDtoList.add(dto);
        });

        //顶级根节点集合
        List<Map<String, Object>> resultDTOList = dtoMap.get(rootName);

        recurDTOList(resultDTOList,dtoMap);

        return resultDTOList;
    }

    /**
     * 将重组好的Map进行树形结构处理
     * @param dtoList 父节点集合(不一定是顶级节点 因为会递归调用)
     * @param sourceMap 组装好的Map集合
     */
    private void recurDTOList(List<Map<String, Object>> dtoList, Map<Object,List<Map<String, Object>>> sourceMap){
        if(CollectionUtils.isEmpty(dtoList))
            return;
        dtoList.forEach(dto -> {
            dto.put(ListToTreeUtils.NODE,sourceMap.get(dto.get(ListToTreeUtils.CODE)));
            recurDTOList((List<Map<String, Object>>) dto.get(ListToTreeUtils.NODE),sourceMap);
        });
    }


    public ListToTreeUtils init(String code, String pcode, String node){
        if(!MyStringUtil.isNullOrEmpty(code)){
            ListToTreeUtils.CODE = code;
        }
        if(!MyStringUtil.isNullOrEmpty(pcode)){
            ListToTreeUtils.PCODE = pcode;
        }
        if(!MyStringUtil.isNullOrEmpty(node)){
            ListToTreeUtils.NODE = node;
        }
        return instance;
    }

    public static ListToTreeUtils getIstance(){
        if (instance == null) {
            synchronized (ListToTreeUtils.class) {
                if (instance == null) {
                    instance = new ListToTreeUtils();
                }
            }
        }
        return instance;
    }

    public static ListToTreeUtils getIstance(String code, String pcode, String node) {
        return getIstance().init(code,pcode,node);
    }
    public static ListToTreeUtils getIstance(String node) {
        return getIstance().init("code","pcode",node);
    }

    public static ListToTreeUtils getDefaultIstance() {
        return getIstance().init("code","pcode","nodes");
    }
}
